﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Web;
using System.Xml;
using Microsoft.Win32;

namespace PmfWeb.Core.Utility
{
    ///<summary>
    /// 文件扩展类
    ///</summary>
    public static class FileUtils
    {
        #region 给图片添加文字水印 public static void TextWater(string filePath, string text)
        /// <summary>
        /// 添加文字水印
        /// </summary>
        /// <param name="filePath">图片地址</param>
        /// <param name="text">水印文字</param>
        public static void TextWater(string filePath, string text)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException("The file don't exist!");
            }

            if (text == string.Empty)
            {
                return;
            }
            //还需要判断文件类型是否为图像类型，这里就不赘述了

            System.Drawing.Image image = System.Drawing.Image.FromFile(filePath);
            Bitmap bitmap = new Bitmap(image, image.Width, image.Height);
            Graphics g = Graphics.FromImage(bitmap);

            float fontSize = 12.0f;             //字体大小
            float textWidth = text.Length * fontSize;  //文本的长度
            //下面定义一个矩形区域，以后在这个矩形里画上白底黑字
            float rectX = 0;
            float rectY = 0;
            float rectWidth = text.Length * (fontSize + 8);
            float rectHeight = fontSize + 8;
            //声明矩形域
            RectangleF textArea = new RectangleF(rectX, rectY, rectWidth, rectHeight);

            Font font = new Font("宋体", fontSize);   //定义字体
            Brush whiteBrush = new SolidBrush(Color.White);   //白笔刷，画文字用
            Brush blackBrush = new SolidBrush(Color.Black);   //黑笔刷，画背景用

            g.FillRectangle(blackBrush, rectX, rectY, rectWidth, rectHeight);

            g.DrawString(text, font, whiteBrush, textArea);
            MemoryStream ms = new MemoryStream();
            //保存为Jpg类型
            bitmap.Save(ms, ImageFormat.Jpeg);

            //输出处理后的图像，这里为了演示方便，我将图片显示在页面中了
            //Response.Clear();
            //Response.ContentType = "image/jpeg";
            //Response.BinaryWrite(ms.ToArray());

            g.Dispose();
            bitmap.Dispose();
            image.Dispose();
        }
        #endregion

        #region 在当前路径上创建日期格式目录(20060205) public static string CreateDir(string sPath)
        /// <summary>
        /// 在当前路径上创建日期格式目录(20060205)
        /// </summary>
        /// <param name="sPath">返回目录名</param>
        /// <returns></returns>
        public static string CreateDir(string sPath)
        {
            string sTemp = DateTime.Today.Year.ToString() + DateTime.Today.Month.ToString("00") + System.DateTime.Today.Day.ToString("00");
            sPath += sTemp;
            DirectoryInfo di = new DirectoryInfo(@sPath); //构造函数创建目录
            if (!di.Exists) di.Create();
            return sTemp;
        }

        ///<summary>
        ///</summary>
        ///<param name="sPath"></param>
        ///<returns></returns>
        public static bool CreateDiv(string sPath)
        {
            string path = "";
            string year = DateTime.Now.Year.ToString();
            string month = DateTime.Now.Month.ToString();
            string day = DateTime.Now.Day.ToString();
            if(Directory.Exists(sPath))
            {
                path = sPath.EndsWith(@"\") ? sPath + year : sPath + @"\" + year;
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }
            return false;
        }

        #endregion

        #region 根据文件扩展名获取当前目录下的文件列表 public static List<string> GetDirFileList(string FileExt)
        /// <summary>
        /// 根据文件扩展名获取当前目录下的文件列表
        /// </summary>
        /// <param name="fileExt">文件扩展名</param>
        /// <returns>返回文件列表</returns>
        public static List<string> GetDirFileList(string fileExt)
        {
            List<string> filesList = new List<string>();
            string[] files = Directory.GetFiles(GetScriptPath, string.Format("*.{0}", fileExt));
            foreach (string s in files)
            {
                filesList.Add(Path.GetFileName(s).ToLower());
            }
            return filesList;
        }
        #endregion

        #region 获取当前访问文件物理目录 public static string GetScriptPath
        /// <summary>
        /// 获取当前访问文件物理目录
        /// </summary>
        /// <returns>路径</returns>
        public static string GetScriptPath
        {
            get
            {
                string paths = HttpContext.Current.Request.ServerVariables["PATH_TRANSLATED"].ToString();
                return paths.Remove(paths.LastIndexOf("\\"));
            }
        }
        #endregion

        #region 创建目录 public static bool CreateFileDir(string path,string name)
        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="name">名称</param>
        /// <returns>创建是否成功</returns>
        [DllImport("dbgHelp", SetLastError = true)]
        private static extern bool MakeSureDirectoryPathExists(string name);

        ///<summary>
        /// 创建文件目录
        ///</summary>
        ///<param name="path">绝对路径</param>
        ///<param name="name">目录名</param>
        ///<returns></returns>
        public static bool CreateFileDir(string path,string name)
        {
            if (!path.EndsWith(@"\")) path = path.Replace(@"/", @"\").Replace(".","_") + @"\";
            if (!name.EndsWith(@"\")) name = name.Replace(@"/", @"\").Replace(".", "_") + @"\";
            return MakeSureDirectoryPathExists(path + name);
        }
        #endregion

        #region 根据文件扩展名获得文件的content-type(文件扩展名如.gif,文件对应的content-type 如:application/gif) public static string GetFileMIME(string fileextension)
        /// <summary>
        /// 根据文件扩展名获得文件的content-type
        /// </summary>
        /// <param name="fileextension">文件扩展名如.gif</param>
        /// <returns>文件对应的content-type 如:application/gif</returns>
        public static string GetFileMIME(string fileextension)
        {
            const string defaultContentType = "application/unknown";

            RegistryKey regkey, fileextkey;
            string filecontenttype = "";
            try
            {
                regkey = Registry.ClassesRoot;
                fileextkey = regkey.OpenSubKey(fileextension);
                if (fileextkey != null)
                    filecontenttype = fileextkey.GetValue("Content Type", defaultContentType).ToString();
                fileextkey = null;
                regkey = null;
            }
            catch
            {
                filecontenttype = defaultContentType;
            }

            return filecontenttype;
        }
        #endregion

        #region 删除文件 public static bool DeleteFile(string FilePath, FilePathType PathType)
        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="filePath">删除的文件路径</param>
        /// <param name="pathType">删除文件路径类型</param>
        /// <returns>成功/失败</returns>
        public static bool DeleteFile(string filePath, FilePathType pathType)
        {
            bool rBool = false;
            switch (pathType)
            {
                case FilePathType.DummyPath:
                    filePath = HttpContext.Current.Server.MapPath(filePath);
                    break;
                case FilePathType.NowDirectoryPath:
                    filePath = HttpContext.Current.Server.MapPath(filePath);
                    break;
                case FilePathType.PhysicsPath:
                    break;
            }
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
                rBool = true;
            }
            return rBool;
        }
        #endregion

        #region 删除文件路径类型(枚举值) public enum FilePathType
        /// <summary>
        /// 删除文件路径类型.1为物理路径,2为虚拟路径,3为当前路径;
        /// </summary>
        public enum FilePathType
        {
            /// <summary>
            /// 物理路径
            /// </summary>
            PhysicsPath = 1,
            /// <summary>
            /// 虚拟路径
            /// </summary>
            DummyPath = 2,
            /// <summary>
            /// 当前目录
            /// </summary>
            NowDirectoryPath = 3
        }
        #endregion

        #region 加载XML文档 public static XmlNodeList LoadXml(string path, string xmlPath, FilePathType pathType)
        ///<summary>
        /// 加载XML文档
        ///</summary>
        ///<param name="path">xml文件路径</param>
        ///<param name="xmlPath">要搜索的节点路径</param>
        ///<param name="pathType">xml文件路径类型.1为物理路径,2为虚拟路径,3为当前路径</param>
        ///<returns></returns>
        public static XmlNodeList LoadXml(string path, string xmlPath, FilePathType pathType)
        {
            switch (pathType)
            {
                case FilePathType.DummyPath:
                    path = HttpContext.Current.Server.MapPath(path);
                    break;
                case FilePathType.NowDirectoryPath:
                    path = HttpContext.Current.Server.MapPath(path);
                    break;
                case FilePathType.PhysicsPath:
                    break;
            }
            if(File.Exists(path))
            {
                XmlDocument xml = new XmlDocument();
                try
                {
                    xml.Load(path);
                }
                catch
                {
                    return null;
                }
                return xml.SelectNodes(xmlPath);
            }
            return null;
        }
        #endregion

        #region 根据Url地址获取文件源码 public static string GetSourceByUrl(string url, Encoding encoding)
        ///<summary>
        /// 根据Url地址获取文件源码 public static string GetSourceByUrl(string url)
        ///</summary>
        ///<param name="url">URL地址</param>
        ///<param name="encoding">编码类型</param>
        ///<returns>源码字符串</returns>
        public static string GetSourceByUrl(string url, Encoding encoding)
        {
            WebRequest request;
            WebResponse response;
            Stream stream = null;
            StreamReader reader = null;
            string result = System.String.Empty;
            try
            {
                request = WebRequest.Create(url);
                response = request.GetResponse();

                stream = response.GetResponseStream();
                reader = new StreamReader(stream, encoding);
                result = reader.ReadToEnd();
            }
            catch (Exception)
            {
                return result;
            }
            finally
            {
                if (stream != null) stream.Close();
                if (reader != null) reader.Close();
            }
            return result;
        }
        #endregion

        #region 根据Url地址获取文件源码 public static string GetSourceByUrl2(string url,Encoding encoding)
        /// <summary>
        /// 根据Url地址获取文件源码
        /// </summary>
        /// <param name="url">URL地址</param>
        /// <param name="encoding">编码类型</param>
        /// <returns>源码字符串</returns>
        public static string GetRemoteSource(string url, Encoding encoding)
        {
            WebClient client =new WebClient();
            //网络凭据
            client.Credentials = CredentialCache.DefaultCredentials;
            byte[] source;
            string result = string.Empty;
            try
            {
                source = client.DownloadData(url);
                result = encoding.GetString(source);
            }
            catch (System.Net.WebException)
            {
                return result;
            }
            catch(System.NotSupportedException)
            {
                return result;
            }
            client.Dispose();
            return result;
        }
        #endregion

        #region 制作图片水印 public static bool CreateBackImage(string strText, string filePath, string savePath, float x, float y)
        /// <summary>
        /// 制作图片水印
        /// </summary>
        /// <param name="strText">要写的文字</param>
        /// <param name="filePath">图片地址(绝对路径)</param>
        /// <param name="savePath">保存路径(绝对路径)</param>
        /// <param name="x">开始书写文字的x坐标</param>
        /// <param name="y">开始书写文字的y坐标</param>
        /// <returns>是否生成成功</returns>
        public static bool CreateBackImage(string strText, string filePath, string savePath, float x, float y)
        {
            bool result = false;
            try
            {
                System.Drawing.Image img = System.Drawing.Image.FromFile(filePath);
                Graphics graphics = Graphics.FromImage(img);
                graphics.DrawImage(img, 0, 0, img.Width, img.Height);

                Font font = new Font("黑体", 14);
                Brush brush = new SolidBrush(Color.Red);
                graphics.DrawString(strText, font, brush, x, y);
                img.Save(savePath);
                result = true;
            }
            catch (Exception)
            {
                return result;
            }
            return result;
        }
        
        #endregion

        #region 生成缩略图 public static bool CreateSmallImage(string oldPath, string newPath, int iWidth, int iHeight)
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="oldPath">源图片地址(绝对路径)</param>
        /// <param name="newPath">缩略图地址(绝对路径)</param>
        /// <param name="iWidth">要缩小的宽度</param>
        /// <param name="iHeight">要缩小的高度</param>
        /// <returns>是否生成成功</returns>
        public static bool CreateSmallImage(string oldPath, string newPath, int iWidth, int iHeight)
        {
            bool result = false;
            System.Drawing.Bitmap objPic, objNewPic;
            try
            {
                objPic = new System.Drawing.Bitmap(oldPath);
                objNewPic = new System.Drawing.Bitmap(objPic, iWidth, iHeight);
                objNewPic.Save(newPath);
                result = true;
            }
            catch (Exception exp)
            {
                throw exp;
            }
            finally
            {
                objPic = null;
                objNewPic = null;
            }
            return result;
        }
        #endregion


        /// <summary>
        /// 在指定的目录下写日志,路径不存在的话会自动创建
        /// </summary>
        /// <param name="path">目录路径(不存在的话会自动创建)</param>
        /// <param name="fileName">要生成的日志文件名</param>
        /// <param name="content">日志信息</param>
        public static void AppendLog(string path, string fileName, string content)
        {
            CreateFileDir(path, "");
            StreamWriter sw = new StreamWriter(path + fileName, true, Encoding.GetEncoding("gb2312"));
            sw.Write("\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t");
            sw.Write(content + "\r\n");
            sw.Close();
        }


    }

    /// <summary>
    /// 文件类型编码
    /// </summary>
    public enum FileExtension
    {
        ///<summary>
        /// JPG文件
        ///</summary>
        JPG = 255216,
        /// <summary>
        /// GIF
        /// </summary>
        GIF = 7173,
        /// <summary>
        /// BMP
        /// </summary>
        BMP = 6677,
        /// <summary>
        /// PNG
        /// </summary>
        PNG = 13780,
        /// <summary>
        /// EXE
        /// </summary>
        EXE = 7790,
        /// <summary>
        /// 
        /// </summary>
        XML = 6063,
        /// <summary>
        /// 
        /// </summary>
        HTML =6033,
        /// <summary>
        /// 
        /// </summary>
        ASPX =239187,
        /// <summary>
        /// 
        /// </summary>
        CS =117115,
        /// <summary>
        /// 
        /// </summary>
        JS =119105,
        /// <summary>
        /// 
        /// </summary>
        TXT = 210187,
        /// <summary>
        /// 
        /// </summary>
        SQL = 255254
}

}